/** \file    exception.h
  * \brief   Handling of windows exceptions.
  * \date    2002, 2003
  * \author  Fedor Chelnokov
  * \version $Header: /home/cscom1r4/cvsroot/cs/include/mswin/exception.h,v 1.1 2004/01/23 21:29:34 cscom1r4 Exp $
  */

#ifndef _exception_h_
#define _exception_h_

#include <exception>

#define WIN32_LEAN_AND_MEAN
#include <windows.h> //GetExceptionInformation()

namespace mswin {

void remember_win_exc_str(LPEXCEPTION_POINTERS e);
const char *get_win_exc_str();

////////////////////
// C++ exceptions //
////////////////////

template <class F, class H>
bool catch_std(F &func, H &handle)
{
    try {
		func();
		return true;
	}
    catch (const std::exception & e) {
		handle(e.what());
    }
	return false;
}

///allows one parameter for func()
template <class F, class P, class H>
bool catch_std(F &func, P &p, H &handle)
{
    try {
		func(p);
		return true;
	}
    catch (const std::exception & e) {
		handle(e.what());
    }
	return false;
}

/////////////////////////////////
// C++ then Windows exceptions //
/////////////////////////////////

///executes func(), catching absolutely all thrown within it all call handle with (const char *) argument
template <class F, class H>
bool catch_all(F &func, H &handle)
{
    __try {
		return catch_std(func, handle);
    } __except(remember_win_exc_str(GetExceptionInformation()), 1) {
		handle(get_win_exc_str());
    }
	return false;
}

///allows one parameter for func()
template <class F, class P, class H>
bool catch_all(F &func, P &p, H &handle)
{
    __try {
		return catch_std(func, p, handle);
    } __except(remember_win_exc_str(GetExceptionInformation()), 1) {
		handle(get_win_exc_str());
    }
	return false;
}

} //namespace mswin

#endif //_exception_h_
